/*
<Copyright (C) 2011 Dru Moore>

This file is part of demorecorder.

vlc-remote is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

demorecorder is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with demorecorder.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "simpletrack.h"
#include <QFile>
#include <QDebug>
#include "utilities.h"

SimpleTrack::SimpleTrack(QObject *parent) :
    QObject(parent)
{
}

SimpleTrack::SimpleTrack(QObject *parent, QString name, QString file, long long start, long long duration, long long mediaStart, long long mediaDuration) :
    QObject(parent)
{
    qDebug("SimpleTrack called");
    this->composition = NULL;
    this->volume = NULL;
    this->bin = NULL;
    this->name = name;
    this->file_path = file;
    this->valid - false;

    this->start = start;
    this->duration = duration;
    this->mediaStart = mediaStart;
    this->mediaDuration = mediaDuration;

    if (0 < file.length() && QFile::exists(file)) {
        qDebug("exists");
        this->file_uri = "file://" + file;
        this->create_bin();
    }
    else {
        qDebug("Doesn't exist");
    }
}


QString SimpleTrack::getName() {
    return name;
}
QString SimpleTrack::getFilePath() {
    return file_path;
}
QString SimpleTrack::getFileUri() {
    return file_uri;
}

void SimpleTrack::setFileSrc(QString path) {

}


void SimpleTrack::setMute(bool mute) {
    Utilities::setGObjectProperty(G_OBJECT(this->volume), "mute", mute);
}
void SimpleTrack::setVolume(double volume) {
    Utilities::setGObjectProperty(G_OBJECT(this->volume), "volume", volume);
}
void SimpleTrack::setPanorama(double panorama) {
    Utilities::setGObjectProperty(G_OBJECT(this->panorama), "panorama", panorama);
}

void SimpleTrack::setValues(long long start, long long duration, long long mediaStart, long long mediaDuration) {
    this->start = start;
    this->duration = duration;
    this->mediaStart = mediaStart;
    this->mediaDuration = mediaDuration;
    if (this->valid) {
        //update the bin values
    }
}

long long SimpleTrack::getDuration() {
    return 0;
}

GstElement* SimpleTrack::getTrackBin() {
    return this->bin;
}

gboolean SimpleTrack::pad_added(GstElement* pipeline, GstPad* srcPad, GstElement* sink) {
    qDebug("pad_added called");
    gboolean result = false;
    g_return_val_if_fail (pipeline != NULL, false);
    qDebug("pipeline fine");
    g_return_val_if_fail (srcPad != NULL, false);
    qDebug("srcPad fine");
    g_return_val_if_fail (sink != NULL, false);
    qDebug("sink fine");
    GstPadLinkReturn ret = gst_pad_link(srcPad, gst_element_get_compatible_pad(sink, srcPad, gst_pad_get_caps(srcPad)));
    qDebug() << "return of pad_link: " << ret;
    result = true;
    return result;
}

void SimpleTrack::create_bin() {
    valid = false;
    QString track_name = "track_bin_" + this->name;
    QString comp_name = "comp_" + this->name;
    QString file_name = "file_" + this->name;
    QString volume_name = "volume_" + this->name;
    QString conv_name = "conv_" + this->name;
    QString silence_name = "silence_" + this->name;
    QString source_name = "source_" + this->name;

    this->bin = gst_element_factory_make("bin", track_name.toLatin1());
    g_assert(this->bin);

    this->composition = gst_element_factory_make("gnlcomposition", comp_name.toLatin1());
    g_assert(this->composition);

    // Create silence
    qDebug() << "creating silence: ";
    this->silence = gst_element_factory_make("gnlsource", source_name.toLatin1());
    g_assert(this->silence);

    if (NULL != this->silence) {
        Utilities::setGObjectProperty(G_OBJECT(this->silence), "start", 0l);
        Utilities::setGObjectProperty(G_OBJECT(this->silence), "duration", this->start + this->duration + 1000); // always
        Utilities::setGObjectProperty(G_OBJECT(this->silence), "media-start", 0l);
        Utilities::setGObjectProperty(G_OBJECT(this->silence), "media-duration", this->start + this->duration + 1000);
        Utilities::setGObjectProperty(G_OBJECT(this->silence), "priority", 10000l); // lower priority

        qDebug() << "adding silent src to silence: ";
        GstElement *silentsrc = gst_element_factory_make("audiotestsrc", silence_name.toLatin1());
        Utilities::setGObjectProperty(G_OBJECT(silentsrc), "wave", 4l); // silence
        gst_bin_add(GST_BIN(this->silence), GST_ELEMENT(silentsrc));

        qDebug() << "adding silence to composition: ";
        gst_bin_add(GST_BIN(this->composition), GST_ELEMENT(this->silence));
    }
    // End create silence


    // Create filesrc
    qDebug() << "adding file src: " << this->file_path;
    this->file_src = gst_element_factory_make("gnlfilesource", file_name.toLatin1());
    g_assert(this->file_src);

    if (NULL != this->file_src) {
        Utilities::setGObjectProperty(G_OBJECT(this->file_src), "location", this->file_path);
        Utilities::setGObjectProperty(G_OBJECT(this->file_src), "start", this->start);
        Utilities::setGObjectProperty(G_OBJECT(this->file_src), "duration", this->duration);
        Utilities::setGObjectProperty(G_OBJECT(this->file_src), "media-start", this->mediaStart);
        Utilities::setGObjectProperty(G_OBJECT(this->file_src), "media-duration", this->mediaDuration);
        Utilities::setGObjectProperty(G_OBJECT(this->file_src), "priority", 1l);

        qDebug() << "adding audio track to composition: ";
        gst_bin_add(GST_BIN(this->composition), GST_ELEMENT(this->file_src));
    }
    // End create filesrc

    this->converter = gst_element_factory_make ("audioconvert", conv_name.toLatin1());
    g_assert(this->converter);

    this->volume = gst_element_factory_make("volume", volume_name.toLatin1());
    g_assert(this->volume);
    Utilities::setGObjectProperty(G_OBJECT(this->volume), "volume", 2.0);
    Utilities::setGObjectProperty(G_OBJECT(this->volume), "mute", false);


    gst_bin_add_many(GST_BIN(this->bin), this->composition, this->converter, this->volume, NULL);

    gst_element_link(GST_ELEMENT(this->converter), GST_ELEMENT(this->volume));

    // we are a source - don't need a sink
    GstPad *srcVolumePad = gst_ghost_pad_new("src", gst_element_get_static_pad(this->volume, "src"));
    //qDebug() << "adding ghost pads";
    gst_element_add_pad(GST_ELEMENT(this->bin), srcVolumePad);
    //qDebug() << "ghost pads added";

    // once we are ready
    g_object_connect ((GObject*) this->composition, "signal::pad-added", &SimpleTrack::pad_added, this->converter, NULL);


    this->valid = true;
}
